package com.ynet.middleground.user.model;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ynet.core.exception.BusinessException;
import com.ynet.host.HostConstants;
import com.ynet.middleground.user.bean.*;
import com.ynet.middleground.user.common.ErrorMessageConstant;
import com.ynet.middleground.user.common.SystemConstant;
import com.ynet.middleground.user.dto.EsignValidDetailDTO;
import com.ynet.middleground.user.dto.IndividualFaceDTO;
import com.ynet.middleground.user.dto.SubbranchDto;
import com.ynet.middleground.user.external.esign.ApiHelper;
import com.ynet.middleground.user.external.esign.ApiUri;
import com.ynet.middleground.user.utils.CommUtils;

/**
 * @author liulx
 * @description E签宝 API 相关服务
 * @date 2019-11-13 10:24
 */
@Component
public class EsignApiModel {

    @Autowired
    private ApiHelper apiHelper;

    @Autowired
    private Mapper mapper;

    /**
     * 个人 2 要素比对
     *
     * @param req 个人 2 要素比对请求对象
     * @return 信息比对业务 id
     * @author liulx
     */
    public String individualVerify2Base(ValidPersonBaseReq req) {
        Map<String, String> params = new HashMap<>(4);
        params.put("name", req.getName());
        params.put("idNo", req.getIdNo());
        Map<String, Object> objectMap =
            apiHelper.sendApiGetData(params, ApiUri.V2_IDENTITY_VERIFY_INDIVIDUAL_BASE, HostConstants.HTTP_METHOD_POST);
        return String.valueOf(objectMap.get("verifyId"));
    }

    /**
     * 【人脸识别认证】个人核身 API 版
     *
     * @param req 获取个人人脸核身认证地址请求信息
     * @return 个人人脸核身地址信息
     */
    public IndividualFaceDTO getIndividualFace(GetIndividualFaceReq req) {
        Map<String, String> params = new HashMap<>(16);
        params.put("name", req.getName());
        params.put("idNo", req.getIdNo());
        params.put("faceauthMode", req.getFaceauthMode());
        params.put("callbackUrl", req.getCallbackUrl());
        params.put("contextId", req.getContextId());
        params.put("notifyUrl", req.getNotifyUrl());
        Map<String, Object> objectMap = apiHelper.sendApiGetData(params, ApiUri.V2_IDENTITY_AUTH_API_INDIVIDUAL_FACE,
            HostConstants.HTTP_METHOD_POST);
        return mapper.map(objectMap, IndividualFaceDTO.class);

    }

    /* add by 2019年11月7日, PM 06:29:51 DaiGaoLe begin */

    /**
     * @Description: 个人运营商3要素信息比对方法
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date: 2019/11/8
     */
    public String personsServiceProviderThreeFactorVerification(PersonsThreeFactorReq requestObject) {
        // 声明变量 begin
        String verifyId = null;
        // "身份证号（大陆二代身份证）不能为空"
        String idNo = requestObject.getIdNo();
        if (!CommUtils.isIdNumber(idNo)) {
            throw new BusinessException(ErrorMessageConstant.ECUC0016_MESSAGE, ErrorMessageConstant.ECUC0016_CODE);
        }
        // 手机号（中国大陆3大运营商）不能为空
        String mobileNo = requestObject.getMobileNo();
        if (!CommUtils.isPhone(mobileNo)) {
            throw new BusinessException(ErrorMessageConstant.ECUC0019_MESSAGE, ErrorMessageConstant.ECUC0019_CODE);
        }
        // "姓名不能为空"
        String name = requestObject.getName();
        // 声明变量 end
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("idNo", idNo);
        params.put("mobileNo", mobileNo);
        params.put("name", name);

        Map<String, Object> objectMap = apiHelper.sendApiGetData(params,
            ApiUri.V2_IDENTITY_VERIFY_INDIVIDUAL_TELECOM3FACTORS, HostConstants.HTTP_METHOD_POST);
        verifyId = (String)objectMap.get("verifyId");
        return verifyId;
    }

    /**
     * @Description: 个人银行卡4要素信息比对方法
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date: 2019/11/8
     */
    public String bank4FactorsVerification(Bank4FactorsReq requestObject) {
        // 声明变量 begin
        String verifyId = null;
        // "身份证号（大陆二代身份证）不能为空"
        String idNo = requestObject.getIdNo();
        if (!CommUtils.isIdNumber(idNo)) {
            throw new BusinessException(ErrorMessageConstant.ECUC0016_MESSAGE, ErrorMessageConstant.ECUC0016_CODE);
        }
        // 手机号（中国大陆3大运营商）不能为空
        String mobileNo = requestObject.getMobileNo();
        if (!CommUtils.isPhone(mobileNo)) {
            throw new BusinessException(ErrorMessageConstant.ECUC0019_MESSAGE, ErrorMessageConstant.ECUC0019_CODE);
        }
        // "姓名不能为空"
        String name = requestObject.getName();
        // "银行卡号不能为空"
        String cardNo = requestObject.getCardNo();
        // 声明变量 end
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("idNo", idNo);
        params.put("mobileNo", mobileNo);
        params.put("name", name);
        params.put("cardNo", cardNo);
        Map<String, Object> objectMap = apiHelper.sendApiGetData(params,
            ApiUri.V2_IDENTITY_VERIFY_INDIVIDUAL_BANK4FACTORS, HostConstants.HTTP_METHOD_POST);
        verifyId = (String)objectMap.get("verifyId");
        return verifyId;
    }

    /**
     * @Description: 企业4要素信息比对方法
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date: 2019/11/8
     */
    public String bureau4FactorsVerification(Bureau4FactorsReq requestObject) {
        // 声明变量 begin
        String verifyId = null;
        // 企业法定代表人身份证号不能为空
        String legalRepCertNo = requestObject.getLegalRepCertNo();
        // 2021-08-17 因山港易付反映e签宝支持港澳、台湾、护照证件类型所以去掉该校验
        // if (!CommUtils.isIdNumber(legalRepCertNo)) {
        // throw new BusinessException(ErrorMessageConstant.ECUC0016_MESSAGE, ErrorMessageConstant.ECUC0016_CODE);
        // }
        // 企业法定代表人姓名不能为空
        String legalRepName = requestObject.getLegalRepName();
        // 企业名称不能为空
        String name = requestObject.getName();
        // 企业统一社会信用代码或工商注册号不能为空
        String orgCode = requestObject.getOrgCode();
        // 声明变量 end
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("legalRepCertNo", legalRepCertNo);
        params.put("legalRepName", legalRepName);
        params.put("name", name);
        params.put("orgCode", orgCode);
        Map<String, Object> objectMap = apiHelper.sendApiGetData(params,
            ApiUri.IDENTITY_VERIFY_ORGANIZATION_ENTERPRISE_BUREAU4FACTORS, HostConstants.HTTP_METHOD_POST);
        verifyId = (String)objectMap.get("verifyId");
        return verifyId;
    }

    /**
     * @Description: 发起企业实名认证4要素校验
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date:
     */
    public String
        enterpriseCertificationFourFactorVerification(EnterpriseCertification4FactorVerificationReq requestObject) {
        // 声明变量 begin
        String verifyId = null;
        // "身份证号（大陆二代身份证）不能为空
        String legalRepIdNo = requestObject.getLegalRepIdNo();
        // 组织机构证件（如营业执照）上的组织机构名称不能为空
        String name = requestObject.getName();
        // 法定代表人名称不能为空
        String legalRepName = requestObject.getLegalRepName();
        // 组织机构证件号不能为空
        String orgCode = requestObject.getOrgCode();

        // add by liwq on 2021-05-20 start
        // 法人证件类型
        // 法人证件类型。不传默认：中国大陆身份证INDIVIDUAL_CH_IDCARD-中国大陆身份证INDIVIDUAL_CH_TWCARD-台湾来往大陆通行证INDIVIDUAL_CH_HONGKONG_MACAO-港澳来往大陆通行证
        // INDIVIDUAL_PASSPORT-护照
        String legalRepCertType = requestObject.getLegalRepCertType();
        if ("INDIVIDUAL_CH_IDCARD".equals(legalRepCertType) || StringUtils.isEmpty(legalRepCertType)) {
            if (!CommUtils.isIdNumber(legalRepIdNo)) {
                throw new BusinessException(ErrorMessageConstant.ECUC0016_MESSAGE, ErrorMessageConstant.ECUC0016_CODE);
            }
        }
        // add by liwq on 2021-05-20 start

        String contextId = requestObject.getContextId();
        String notifyUrl = requestObject.getNotifyUrl();
        // 声明变量 end
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("legalRepIdNo", legalRepIdNo);
        params.put("legalRepName", legalRepName);
        params.put("name", name);
        params.put("orgCode", orgCode);
        if (StringUtils.isNotEmpty(contextId)) {
            params.put("contextId", contextId);
        }
        if (StringUtils.isNotEmpty(legalRepCertType)) {
            params.put("legalRepCertType", legalRepCertType);
        }
        if (StringUtils.isNotEmpty(notifyUrl)) {
            params.put("notifyUrl", notifyUrl);
        }

        Map<String, Object> objectMap = apiHelper.sendApiGetData(params,
            ApiUri.V2_IDENTITY_AUTH_API_ORGANIZATION_ENTERPRISE_FOURFACTORS, HostConstants.HTTP_METHOD_POST);
        verifyId = (String)objectMap.get("flowId");
        return verifyId;
    }

    /**
     * @Description: 发起随机金额打款认证
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date:
     */

    public String transferRandomAmount(TransferRandomAmountReq requestObject) {
        // 声明变量 begin
        String returnsResult = SystemConstant.SYSTEM_SUCCESS;
        // 对公账号开户行总行名称不能为空")
        String bank = requestObject.getBank();
        // 银行卡号信息不能为空")
        String cardNo = requestObject.getCardNo();
        // 对公账号开户行所在城市名称不能为空")
        String city = requestObject.getCity();
        // 联行号（名词解释） 可通过 查询打款银行信息 获取，或第三方数据库获取不能为空")
        String cnapsCode = requestObject.getCnapsCode();
        String contextId = requestObject.getContextId();
        // 认证流程Id不能为空！")
        String flowId = requestObject.getFlowId();
        String notifyUrl = requestObject.getNotifyUrl();
        // 对公账号开户行总行名称不能为空")
        String province = requestObject.getProvince();
        // 对公账号开户行支行名称全称不能为空")
        String subbranch = requestObject.getSubbranch();

        String url = ApiUri.V2_IDENTITY_AUTH_PUB_ORGANIZATION_FLOWID_TRANSFERRANDOMAMOUNT;
        // 声明变量 end
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("bank", bank);
        params.put("cardNo", cardNo);
        params.put("city", city);
        params.put("cnapsCode", cnapsCode);
        params.put("flowId", flowId);
        params.put("province", province);
        params.put("subbranch", subbranch);
        if (StringUtils.isNotEmpty(contextId)) {
            params.put("contextId", contextId);
        }
        if (StringUtils.isNotEmpty(notifyUrl)) {
            params.put("notifyUrl", notifyUrl);
        }
        apiHelper.sendApiGetData(params, url.replace("{flowId}", "flowId"), HostConstants.HTTP_METHOD_PUT);
        return returnsResult;
    }

    /**
     * @Description: 随机打款金额校验
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date:
     */
    public String verifyRandomAmountReq(VerifyRandomAmountReq requestObject) {
        // 声明变量 begin
        String returnsResult = SystemConstant.SYSTEM_SUCCESS;
        String url = ApiUri.V2_IDENTITY_AUTH_PUB_ORGANIZATION_FLOWID_VERIFYRANDOMAMOUNT;
        // 对公账号收到的随机金额数值不能为空
        BigDecimal amount = requestObject.getAmount();
        // 认证流程Id不能为空
        String flowId = requestObject.getFlowId();
        // 声明变量 end
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("amount", amount.toString());
        params.put("flowId", flowId);
        apiHelper.sendApiGetData(params, url.replace("{flowId}", "flowId"), HostConstants.HTTP_METHOD_PUT);
        return returnsResult;
    }

    /**
     * @Description: 查询打款银行信息
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date:
     */
    public List<SubbranchDto> subbranch(SubbranchReq requestObject) {
        // 声明变量 begin
        String url = ApiUri.V2_IDENTITY_AUTH_PUB_ORGANIZATION_FLOWID_SUBBRANCH;
        // 银行名称搜索关键字，建议输入完整的银行名称不能为空
        String keyWord = requestObject.getKeyWord();
        // 认证流程Id不能为空
        String flowId = requestObject.getFlowId();
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("keyWord", keyWord);
        params.put("flowId", flowId);
        // "/v2/identity/auth/pub/organization/" + flowId+ "/subbranch"
        Map<String, Object> objectMap =
            apiHelper.sendApiGetData(params, url.replace("{flowId}", "flowId"), HostConstants.HTTP_METHOD_GET);
        List<Map<String, String>> list = (List<Map<String, String>>)objectMap.get("list");
        if (list == null) {
            return Collections.EMPTY_LIST;
        }
        List<SubbranchDto> subbranchDtos =
            list.stream().map(obj -> mapper.map(obj, SubbranchDto.class)).collect(Collectors.toList());
        return subbranchDtos;
    }

    /* add by 2019年11月7日, PM 06:29:51 DaiGaoLe begin */

    /**
     * 发起运营商3要素核身认证
     *
     * @param reqObj 运营商3要素核身认证请求对象
     * @return 流程flowId
     * @author liulx
     */
    public String validTelecom3Factors(ValidPersonTelecom3Req reqObj) {
        Map<String, String> params = new HashMap<>();
        params.put("name", reqObj.getName());
        params.put("idNo", reqObj.getIdNo());
        params.put("mobileNo", reqObj.getMobileNo());
        params.put("contextId", reqObj.getContextId());
        params.put("notifyUrl", reqObj.getNotifyUrl());
        Map<String, Object> objectMap =
            apiHelper.sendApiGetData(params, ApiUri.PERSON_TELECOM_3_FACTORS, HostConstants.HTTP_METHOD_POST);
        return String.valueOf(objectMap.get("flowId"));
    }

    /**
     * 发起银行卡4要素核身认证
     *
     * @param reqObj 银行卡4要素核身认证请求对象
     * @return 流程flowId
     * @author liulx
     */
    public String validBankCard4Factors(ValidPersonBankCard4Req reqObj) {
        Map<String, String> params = new HashMap<>();
        params.put("name", reqObj.getName());
        params.put("idNo", reqObj.getIdNo());
        params.put("mobileNo", reqObj.getMobileNo());
        params.put("bankCardNo", reqObj.getBankCardNo());
        params.put("contextId", reqObj.getContextId());
        params.put("notifyUrl", reqObj.getNotifyUrl());
        Map<String, Object> objectMap =
            apiHelper.sendApiGetData(params, ApiUri.PERSON_BANKCARD_4_FACTORS, HostConstants.HTTP_METHOD_POST);
        return String.valueOf(objectMap.get("flowId"));
    }

    /**
     * 查询认证信息
     *
     * @param detailReq 查询认证信息请求对象
     * @return e签宝查询认证详情传输对象
     * @author liulx
     */
    public EsignValidDetailDTO getValidDetail(QueryEsignValidDetailReq detailReq) {
        Map<String, String> params = new HashMap<>();
        params.put("flowId", detailReq.getFlowId());
        Map<String, Object> objectMap = apiHelper.sendApiGetData(params,
            ApiUri.QUERY_VALID_DETAIL.replace("{flowId}", detailReq.getFlowId()), HostConstants.HTTP_METHOD_GET);
        return mapper.map(objectMap, EsignValidDetailDTO.class);
    }

    /**
     * 手机号验证码校验
     *
     * @param req e签宝手机验证码校验请求对象
     * @param type 默认0: 手机号验证码校验, 1: 银行卡预留手机号验证码校验
     */
    public void checkVerificationCode(CheckEsignVerificationCodeReq req, int type) {
        Map<String, String> params = new HashMap<>();
        params.put("flowId", req.getFlowId());
        params.put("authcode", req.getAuthcode());
        String url = ApiUri.MOBILE_VERIFICATION_CODE_CHECK;
        if (type == 1) {
            url = ApiUri.BANK_MOBILE_VERIFICATION_CODE_CHECK;
        }
        apiHelper.sendApi(params, url.replace("{flowId}", req.getFlowId()), HostConstants.HTTP_METHOD_PUT);
    }

    /**
     * @Description: 企业2要素信息比对方法
     * @Param:
     * @return:
     * @Author: syf
     * @Date: 2022/04/19
     */
    public String bureau2FactorsVerification(Bureau2FactorsReq requestObject) {
        // 声明变量 begin
        String verifyId = null;
        // 企业名称不能为空
        String name = requestObject.getName();
        // 企业统一社会信用代码或工商注册号不能为空
        String orgCode = requestObject.getOrgCode();
        // 声明变量 end
        // 通过url传递的参数，POST和GET均可
        Map<String, String> params = new HashMap<>();
        params.put("name", name);
        params.put("orgCode", orgCode);
        Map<String, Object> objectMap = apiHelper.sendApiGetData(params,
            ApiUri.IDENTITY_VERIFY_ORGANIZATION_ENTERPRISE_BUREAU2FACTORS, HostConstants.HTTP_METHOD_POST);
        verifyId = (String)objectMap.get("verifyId");
        return verifyId;
    }
}
